import type { ApplicationModel } from '@/apis/model/application'
import type { SimpleRegion } from '@/apis/model/region'
import {
  getApplicationDetailApi,
  getApplicationPermissionsDetailApi,
} from '@/apis/modules/application'
import { getBandwidthTypeListApi } from '@/apis/modules/bandwidthType'
import { getComputeMachineGroupListApi } from '@/apis/modules/group'
import { useLoading } from '@/composables/useLoading'
import { isEmpty } from 'lodash-es'

/**
 * 方法执行顺序
 * 1. 先获取区域
 * 2. 获取成功之后构建默认表单，并获取分组和带宽类型
 * 3. 获取权限配置
 * 4. 将权限配置填充到表单中
 */

type ApplicationPermissionState = Record<
  string,
  {
    vps: string[]
    dedicated: string[]
    bandwidthType: string[]
  }
>
interface ConfigItem {
  label: string
  value: string
  options: {
    label: string | undefined
    value: string | number | undefined
  }[]
}
// 定义目标数组结构的类型
interface ResourceListItem {
  app_id: string
  region_id: string
  resource_type: number // 1: vps, 2: dedicated, 3: bandwidthType
  resource_ids: string[]
}

export function useDataSource() {
  const route = useRoute()

  const { parse } = useLangField()

  const { loading } = useLoading()
  const record = ref<ApplicationModel>()

  const formState = ref<ApplicationPermissionState>({})

  const getApplication = () => {
    getApplicationDetailApi({ app_id: route.params?.appid as string }).then(
      (res) => {
        record.value = res.info
      },
    )
  }
  // 获取权限
  const { run: getApplicationPermissions } = useListRequest(
    getApplicationPermissionsDetailApi,
    {
      loading,
      noPagination: true,
      afterFn: (list) => {
        formState.value = reverseToFormState(list as ResourceListItem[])
      },
      params: computed(() => ({
        app_id: route.params?.appid as string,
      })),
    },
  )

  // 分组
  const { data: groups, run: getMachineGroupList } = useListRequest(
    getComputeMachineGroupListApi,
    {
      loading,
      noPagination: true,
    },
  )
  // 带宽类型
  const { data: bandwidthTypes, run: getBandwidthTypeList } = useListRequest(
    getBandwidthTypeListApi,
    {
      loading,
      noPagination: true,
    },
  )

  function buildDefaultState(regions: Array<SimpleRegion>) {
    return regions.reduce((prev, cur) => {
      prev[`${cur.id}`] = {
        vps: [],
        dedicated: [],
        bandwidthType: [],
      }
      return prev
    }, {} as ApplicationPermissionState)
  }

  // 区域
  const { allRegionOptions } = useRegions({
    after: (regions) => {
      formState.value = buildDefaultState(regions)

      getMachineGroupList()
      getBandwidthTypeList()
      getApplicationPermissions()
    },
  })
  // type: 1- 云服务器 2- 裸金属
  const bandwidthTypeWithRegion = computed<
    (regionId: string) => LabelValue<string>[]
  >(
      () => (regionId: string) =>
        bandwidthTypes.value
          ?.filter(item => item.region_id === regionId)
          .map((item) => {
            const field = parse(item.name || '')
            return {
              label: field?.['zh-CN'] || '-',
              value: String(item.id),
            }
          }),
      )
  const vpsGroups = computed(() =>
    groups.value
      ?.filter(item => item.type === 1)
      .map(item => ({
        label: String(item.name),
        value: String(item.id),
        region_id: item.region_id,
      })),
  )

  const dedicatedGroups = computed(() =>
    groups.value
      ?.filter(item => item.type === 2)
      .map(item => ({
        label: String(item.name),
        value: String(item.id),
        region_id: item.region_id,
      })),
  )

  const options = computed<(regionId: string) => Array<ConfigItem>>(
    () => (regionId: string) => {
      return [
        {
          label: '云服务器分组',
          value: 'vps',
          options: vpsGroups.value.filter(item => item.region_id === regionId),
        },
        {
          label: '裸金属分组',
          value: 'dedicated',
          options: dedicatedGroups.value.filter(
            item => item.region_id === regionId,
          ),
        },
        {
          label: '带宽类型',
          value: 'bandwidthType',
          options: bandwidthTypeWithRegion.value(regionId),
        },
      ]
    },
  )

  // 发送的数据 list
  const getparamsList = () => {
    // 定义资源类型对应的编号映射
    const typeMap = {
      vps: 1,
      dedicated: 2,
      bandwidthType: 3,
    } as const

    const app_id = route.params?.appid as string
    return Object.entries(formState.value).reduce<ResourceListItem[]>(
      (acc, [region_id, config]) => {
        // 遍历每个 region 下的资源类型配置
        Object.entries(config).forEach(([key, resource_ids]) => {
          const resource_type = typeMap[key as keyof typeof typeMap]
          if (resource_ids.length) {
            // 如果某个类型下有资源 ID，构建一条记录推入数组
            acc.push({ app_id, region_id, resource_type, resource_ids })
          }
        })
        return acc
      },
      [],
    ) // 初始为一个空数组
  }
  const getParams = () => {
    return {
      app_id: route.params?.appid as string,
      list: getparamsList(),
    }
  }

  function reverseToFormState(
    list: ResourceListItem[],
  ): ApplicationPermissionState {
    const typeMap: Record<number, keyof ApplicationPermissionState[string]> = {
      1: 'vps',
      2: 'dedicated',
      3: 'bandwidthType',
    }

    return list.reduce<ApplicationPermissionState>(
      (acc, { region_id, resource_type, resource_ids }) => {
        // 如果该 region_id 还没有初始化，就创建一个默认结构
        if (!acc[region_id]) {
          acc[region_id] = {
            vps: [],
            dedicated: [],
            bandwidthType: [],
          }
        }

        // 获取对应的资源类型字段名（如 "vps"）
        const key = typeMap[resource_type]

        // 填入对应资源 ID 数组
        acc[region_id][key] = resource_ids

        return acc
      },
      {},
    ) // 初始为一个空对象
  }
  onMounted(() => {
    getApplication()
  })

  const validateState = computed(() => {
    const res = Object.keys(formState.value).reduce(
      (acc: Recordable<string>, cur: string) => {
        const item = formState.value[cur]
        // 分组是否为空
        const groupEmpty = isEmpty(item.dedicated) && isEmpty(item.vps)
        // 带宽类型是否为空
        const bandwidthEmpty = isEmpty(item.bandwidthType)
        // 如果分组为空且带宽类型不为空，提示请配置分组
        if (groupEmpty && !bandwidthEmpty) {
          acc[cur] = '请配置分组'
        }
        // 如果分组不为空且带宽类型为空，提示请配置带宽类型
        if (!groupEmpty && bandwidthEmpty) {
          acc[cur] = '请配置带宽类型'
        }
        return acc
      },
      {} as Recordable,
    )
    if (isEmpty(res)) {
      return void '验证失败'
    }
    return res
  })

  return {
    record,
    reverseToFormState,
    getParams,
    options,
    allRegionOptions,
    formState,
    loading,
    getparamsList,
    validateState,
  }
}
